package com.zzyl.serve.service.impl;

import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zzyl.common.constant.CacheConstants;
import com.zzyl.common.core.domain.model.LoginUser;
import com.zzyl.common.utils.ServletUtils;
import com.zzyl.common.utils.WechatUtil;
import com.zzyl.framework.web.service.TokenService;
import com.zzyl.serve.domain.*;
import com.zzyl.serve.dto.BindDto;
import com.zzyl.serve.dto.MemberLoginDto;
import com.zzyl.serve.mapper.ElderMapper;
import com.zzyl.serve.mapper.FamilyMemberMapper;
import com.zzyl.serve.service.IFamilyMemberService;
import com.zzyl.serve.vo.FamilyElderPageVo;
import com.zzyl.serve.vo.FamilyElderVo;
import com.zzyl.serve.vo.MemberLoginVo;
import com.zzyl.serve.vo.ServicePropertiesVo;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.*;

/**
 * 老人家属Service业务层处理
 *
 * @author liuyp
 * @date 2025-08-21
 */
@Service
@Slf4j
public class FamilyMemberServiceImpl extends ServiceImpl<FamilyMemberMapper, FamilyMember> implements IFamilyMemberService {
    private static final List<String> nickNamePool = List.of("生活更美好",
            "大桔大利",
            "日富一日",
            "好柿开花",
            "柿柿如意",
            "一椰暴富",
            "大柚所为",
            "杨梅吐气",
            "天生荔枝");
    @Autowired
    private FamilyMemberMapper familyMemberMapper;
    @Autowired
    private WechatUtil wechatUtil;
    @Autowired
    private TokenService tokenService;
    @Autowired
    private ElderMapper elderMapper;
    @Qualifier("redisTemplate")
    @Autowired
    private RedisTemplate<Object, Object> redisTemplate;

    /**
     * 查询老人家属
     *
     * @param id 老人家属主键
     * @return 老人家属
     */
    @Override
    public FamilyMember selectFamilyMemberById(Long id) {
        return familyMemberMapper.selectById(id);
    }

    /**
     * 查询老人家属列表
     *
     * @param familyMember 老人家属
     * @return 老人家属
     */
    @Override
    public List<FamilyMember> selectFamilyMemberList(FamilyMember familyMember) {
        return familyMemberMapper.selectFamilyMemberList(familyMember);
    }

    /**
     * 新增老人家属
     *
     * @param familyMember 老人家属
     * @return 结果
     */
    @Override
    public int insertFamilyMember(FamilyMember familyMember) {
        return familyMemberMapper.insert(familyMember);
    }

    /**
     * 修改老人家属
     *
     * @param familyMember 老人家属
     * @return 结果
     */
    @Override
    public int updateFamilyMember(FamilyMember familyMember) {
        return familyMemberMapper.updateById(familyMember);
    }

    /**
     * 批量删除老人家属
     *
     * @param ids 需要删除的老人家属主键
     * @return 结果
     */
    @Override
    public int deleteFamilyMemberByIds(Long[] ids) {
        return familyMemberMapper.deleteBatchIds(Arrays.asList(ids));
    }

    /**
     * 删除老人家属信息
     *
     * @param id 老人家属主键
     * @return 结果
     */
    @Override
    public int deleteFamilyMemberById(Long id) {
        return familyMemberMapper.deleteById(id);
    }

    @Override
    public MemberLoginVo login(MemberLoginDto dto) {
        // 1. 向微信平台发请求获取openid
        String openid = wechatUtil.getOpenid(dto.getCode());
        // 2. 向微信平台发请求获取手机号
        String phone = wechatUtil.getPhone(dto.getPhoneCode());
        // 3. 根据微信账号openid，到数据库表里查询一下
        LambdaQueryWrapper<FamilyMember> wrapper = Wrappers.<FamilyMember>lambdaQuery().eq(FamilyMember::getOpenId, openid);
        FamilyMember familyMember = familyMemberMapper.selectOne(wrapper);
        // 4. 判断是否查到家属信息了
        if (familyMember == null) {
            familyMember = new FamilyMember();
            // 给用户设置昵称，而不是使用了用户的微信昵称。昵称：从nickNamePool里随机取一个昵称，再拼接上手机号后4位
            familyMember.setName(nickNamePool.get(new Random().nextInt(nickNamePool.size())) + phone.substring(phone.length() - 4));
            familyMember.setOpenId(openid);
            familyMember.setPhone(phone);
            save(familyMember);
        } else {
            // 如果手机号 和 数据库里的手机号不同，则需要更新手机号
            if (!phone.equals(familyMember.getPhone())) {
                familyMember.setPhone(phone);
                updateById(familyMember);
            }
        }
        // 5. 准备返回值
        MemberLoginVo vo = new MemberLoginVo();
        vo.setNickName(familyMember.getName());
        Map<String, Object> claims = new HashMap<>();
        claims.put("id", familyMember.getId());
        claims.put("name", familyMember.getName());
        vo.setToken(tokenService.createToken(claims));
        return vo;
    }

    @Override
    public void bind(BindDto dto) {
        //1.先拿到用户的id
        // 获取当前HTTP请求
        HttpServletRequest request = ServletUtils.getRequest();
        // 从token中解析出登录用户信息
        String authorization = request.getHeader("Authorization");
        // 处理Bearer前缀
        String token = authorization;
        if (authorization != null && authorization.startsWith("Bearer ")) {
            token = authorization.replace("Bearer ", "");
        }

        try {
            Claims claims = tokenService.parseToken(token);
            // 从claims中获取登录时存储的用户ID（注意不是getId()）
            Long userId = ((Number) claims.get("id")).longValue();
            System.out.println("userId = " + userId);

            //2.拿到老人的id
            //根据传过来的老人身份证对老人表进行查询
            LambdaQueryWrapper<Elder> wrapper = Wrappers.<Elder>lambdaQuery().eq(Elder::getIdCardNo, dto.getIdCard());
            Elder elder = elderMapper.selectOne(wrapper);

            // 添加空值检查
            if (elder == null) {
                throw new RuntimeException("找不到对应的老人信息");
            }

            Long elderId = elder.getId();

            //3.获取创建人id
            Long createBy = userId;

            //准备实体类对象保存
            FamilyMemberElder familyMemberElder = new FamilyMemberElder();
            familyMemberElder.setFamilyMemberId(userId);
            familyMemberElder.setElderId(elderId);
            familyMemberElder.setCreateBy(String.valueOf(createBy));
            familyMemberElder.setRemark(dto.getRemark());

            //保存
            familyMemberMapper.save(familyMemberElder);

        } catch (Exception e) {
            System.err.println("解析token失败: " + e.getMessage());
            e.printStackTrace();
            throw new RuntimeException("获取用户信息失败");
        }
    }

    @Override
    public List<FamilyMemberElder> queryfamilylist() {
        ArrayList<FamilyElderVo> familyElderVos = new ArrayList<>();

        List<FamilyMemberElder> list = familyMemberMapper.listAll();
        for (FamilyMemberElder familyMemberElder : list) {

            String name = familyMemberMapper.getElderName(familyMemberElder.getElderId());
            familyMemberElder.setElderName(name);
        }


        return list;
    }

    @Override
    public List<FamilyElderPageVo> pageQuery(Integer pageNum, Integer pageSize) {


        Integer offset = (pageNum - 1) * pageSize;

        return familyMemberMapper.pageQuery(offset, pageSize);

    }

    @Override
    public List<ServicePropertiesVo> queryIotData(String iotId) {


            // 从Redis中获取JSON字符串
            Object cachedData = redisTemplate.opsForHash().get(CacheConstants.IOT_DEVICE_LAST_DATA, iotId);


            String jsonStr = (String) cachedData;
            // 转换回List<DeviceData>

            List<ServicePropertiesVo> list = new ArrayList<>();


            List<DeviceData> deviceDataList = JSONUtil.toList(jsonStr, DeviceData.class);

            for (DeviceData deviceData : deviceDataList) {
                ServicePropertiesVo vo = new ServicePropertiesVo();

                String functionId = deviceData.getFunctionId();
                LocalDateTime alarmTime = deviceData.getAlarmTime();
                String dataValue = deviceData.getDataValue();
                double value = Double.parseDouble(dataValue);

                vo.setFunctionId(functionId);
                vo.setEventTime(String.valueOf(alarmTime));
                vo.setValue(value);
                list.add(vo);
            }
            return list;
    }

    @Autowired
    private FamilyMemberElderServiceImpl familyMemberElderService;
    /**
     * 根据id删除家属绑定的老人
     * @param id
     */
    @Override
    public void deleteById(Integer id) {
        familyMemberElderService.removeById(id);
    }
}